<!--
    基于vxe-grid的二次封装

-->
<template>
    <div class="grid-class">
        <vxe-grid
            :id="tableId"
            ref="xGrid"
            :checkbox-config="checkboxConfig"
            :columns="tableColumn"
            :custom-config="customConfig"
            :data="tableData"
            :edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
            :export-config="editConfig" :import-config="{}" :print-config="{}"
            :toolbar-config="showTableToolbar ? tableToolbar : null"
            :row-config="rowConfig" :tooltip-config={} align="center" border="full" height="100%" keep-source
            resizable show-overflow="tooltip" @custom="custom" @scroll="scroll" @cell-click="cellClick"
            @cell-dblclick="cellDblclick" @checkbox-change="checkboxChange" @checkbox-all="checkboxAll"
            @cell-mouseenter="cellMouseenter" @cell-mouseleave="cellMouseleave" @resizable-change="resizableChange"
            @radio-change="radioChange"
            @current-change="currentChange" @header-cell-click="headCellClick">
        </vxe-grid>
        <div class="table-title">{{tableTitle || ""}}</div>
        <div class="button-title">
            <el-button size="medium" :type="btn.type" v-for="(btn,index) of buttonList" :key="index" @click="btnClick(btn)">{{btn.name}}</el-button>
        </div>
    </div>
</template>

<script>
export default {
	components: {},

	props: {
		tableId: String,//表格ID
        tableTitle: String,//表格标题
        showTableToolbar: {
            type: Boolean,
            default: true
        },//是否展示顶部操作
		tableColumn: Array,//表格列
		tableData: Array,//表格数据
		oprConfig: Array,//操作列配置项
        buttonList: [],//按钮组
		showOprColumn: {
			type: Boolean,
			default: true
		},//是否展示操作列
		showCheckbox: {
			type: Boolean,
			default: true
		},//是否展示多选框列
        editConfig: Object
	},
	data () {
		return {
			// 个性化信息配置项
			customConfig: {
				storage: true,
				updateStore: this.updateStore,
				checkMethod: this.checkColumnMethod,
				allowSort: false,
				allowFixed: false,
				// storage: false
			},
			// 复选框配置项
			checkboxConfig: {
				highlight: true,
			},
			// 行配置信息
			rowConfig: {
				height: 40,// 设置行高为40像素
				isCurrent: true,
				isHover: true
			},
			tableToolbar: {
				buttons: [],
				tools: [],
				refresh: true,
				import: true,
				export: true,
				print: true,
				zoom: false,
				custom: true
			},
		}
	},
	created () {

	},
	mounted () {

	},
	methods: {
        // 按钮点击事件
        btnClick(btn){
            this.$emit("btnClick",btn);
        },
		// 自定义列配置的回调
		custom ($event) {
			// console.log("🚀 ~ e", $event)
			// console.log("🚀 ~ ", this.$refs.xGrid.getCustomStoreData())
		},
		// 滚动事件
		scroll (e) {
			// console.log("🚀 ~ e", e)
			/**
			 * scrollTop（可视区域顶部到文档流顶部距离）
			 * scrollHeight（文档内容实际高度，包括溢出部分）
			 * clientHeight（窗口可视范围高度）。当
			 * clientHeight加上scrollTop等于scrollHeight时，意味着已到达内容底部，可用于实现滚动加载更多内容。
			 * */
			const {$event} = e
			const {scrollTop, clientHeight, scrollHeight} = $event.target
			// 检查是否滚动到底部
			if (scrollHeight - scrollTop <= clientHeight) {
				this.$emit('reachBottom')
			}
		},
		// 点击表头
		headCellClick () {

		},
		// 点击单元格
		cellClick ({
			row,
			rowIndex,
			$rowIndex,
			column,
			columnIndex,
			$columnIndex,
			triggerRadio,
			triggerCheckbox,
			triggerTreeNode,
			triggerExpandNode,
			$event
		}) {
			// console.log("单击$event", row, rowIndex, column, columnIndex);

			this.$emit('cellClick', row, rowIndex, column, columnIndex)
		},
		// 双击单元格
		cellDblclick ({
			row,
			rowIndex,
			$rowIndex,
			column,
			columnIndex,
			$columnIndex,
			triggerRadio,
			triggerCheckbox,
			triggerTreeNode,
			triggerExpandNode,
			$event
		}) {
			// console.log("双击$event", row, rowIndex, column, columnIndex);
			this.$emit('cellDblclick', row, rowIndex, column, columnIndex)
		},
		// 只对 row-config.isCurrent 有效，当手动选中行并且值发生改变时触发的事件
		currentChange ({newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event}) {
			// console.log(newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event);
			this.$emit('currentChange', newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event)
		},
        // 单选改变
        radioChange({newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event}){
            this.$emit('radioChange', newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event)
        },
		// 删除复选框选中的行数据
		removeCheckboxRow () {
			this.$refs.xGrid.removeCheckboxRow()
		},
		// 用于 row-config.isCurrent，设置某一行为高亮状态
		setCurrentRow (row) {
			this.$refs.xGrid.setCurrentRow(row)
		},
        insert(records){
            this.$refs.xGrid.insert(records)
        },
        insertAt(records, row){
            this.$refs.xGrid.insertAt(records, row)
        },
		// 局部加载数据
		reloadRow (rows, record, field) {
			this.$refs.xGrid.setCurrentRow(rows, record, field)
		},
		// 加载数据（对于表格数据需要重载、局部递增场景下可能会用到）
		loadData (data) {
			this.$refs.xGrid.loadData(data)
		},
		// 加载数据并清除所有状态（对于表格数据需要重载、局部更新被修改的数据）
		reloadData (data) {
			this.$refs.xGrid.reloadData(data)
		},
		// 加载列配置（对于表格列需要重载、局部递增场景下可能会用到）
		loadColumn (columns) {
			this.$refs.xGrid.loadColumn(columns)
		},
		// 选择行数据
		checkboxChange ({newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event}) {
			// console.log("🚀 ~ $event", newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex)
			this.$emit('checkboxChange', newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex)
		},
		// 全选/全不选
		checkboxAll ({checked, $event}) {
			// console.log("checked", checked, $event);
			this.$emit('checkboxAll', checked, $event)
		},
		// 判断是否全部数据已经选中
		diyGetAllDataIsChecked () {
			let checked = true
			this.tableData.forEach((item) => {
				if (!item.checked) {
					checked = false
				}
			})
			return checked
		},
		// 自定义选中的数据数量
		diyGetCheckedNumber () {
			let number = 0
			this.tableData.forEach((row) => {
				row.checked = true
				number += 1
			})
			console.log('🚀 ~ number', number)
			return number
		},
		// 单元格的icon点击
		cellIconClick (icon, column, row) {
			console.log('icon, column, row', icon, column, row)
			// this.$forceUpdate()
			this.$emit('cellIconClick', icon, column, row)
		},
		// 打开自定义列配置窗口
		openCustom () {
			this.$refs.xGrid.openCustom()
		},
		// 列宽变化事件
		resizableChange (e) {
			console.log('🚀 ~ e', e)
		},
		// 鼠标滑过单元格
		cellMouseenter ($event) {
			// console.log("🚀 ~ e", $event)
			this.$emit('cellMouseenter', $event)
		},
		// 鼠标离开单元格
		cellMouseleave ($event) {
		
		},
		// 自定义的排序方法 列 升序/倒序 是否文件类型
		sortData (column, type, fileSort) {
			// console.log("🚀 ~ column", column)
			// console.log("🚀 ~ this.tableColumnOpr", this.tableColumnOpr)
			this.tableColumnOpr.forEach((col) => {
				if (fileSort && fileSort === 'file') {
					// 如果是全部类型。排序数组为["all"]
					if (type === 'all') {
						col.fileSortList = ['all']
					} else {
						if (col.fileSortList && col.fileSortList.length > 0) {
							let find = col.fileSortList.find((fie) => {
								return fie === type
							})
							if (find) {
								for (let index = col.fileSortList.length - 1; index >= 0; index--) {
									const element = col.fileSortList[index]
									if (find === element) {
										col.fileSortList.splice(index, 1)
									}
								}
							} else {
								col.fileSortList.push(type)
							}
						} else {
							col.fileSortList = [type]
						}
						col.fileSortList = col.fileSortList.filter((f) => {
							return f !== 'all'
						})
					}
					this.$forceUpdate()
				} else {
					if (col.sort) {
						col.sort = 'default'
					}
					if (col.field === column.field) {
						col.sort = type
					}
				}
			})
			let fileColumn = this.tableColumnOpr.find((col => {
				return col.field === 'name'
			}))
			let sortColumn = this.tableColumnOpr.find((col => {
				return col.sort && col.sort !== 'default'
			}))
			let fileSortList = fileColumn ? fileColumn.fileSortList : null
			let sort = sortColumn ? sortColumn.sort : null
			this.$emit('sort', sortColumn, fileSortList)
		},
		// 操作列里边的按钮点击回调
		oprClick (opr, row) {
			this.$emit('oprClick', opr, row, this.tableId)
		},
		// 只对 storage 有效，重写默认的保存方法，比如需要将自定义列信息保持到服务器时可能会用到
		updateStore (params) {
			console.log('🚀 ~ updateStore', params)
			let fixedData = params.storeData.fixedData
			let resizableData = params.storeData.resizableData
			let visibleData = params.storeData.visibleData
			// 根据params.storeData.sortData判断是否存在排序操作
			// 如果存在，将tableColumn重新排序。
			let tableColumn = JSON.parse(JSON.stringify(this.tableColumn))
			let sortArr = []
			if (params.storeData.sortData) {
				let sortData = params.storeData.sortData
				for (const paramsKey in sortData) {
					sortArr.push({
						field: paramsKey,
						sort: sortData[paramsKey]
					})
				}
			}
			tableColumn.sort((a, b) => {
				let aid, bid
				sortArr.forEach((item, index) => {
					if (item.field === a.field) aid = index
					if (item.field === b.field) bid = index
				})
				return aid - bid
			})

			tableColumn.forEach((column) => {
				// 列宽
				if (resizableData) {
					for (const key in resizableData) {
						if (key === column.field) {
							column.width = resizableData[column.field]
						}
					}
				}
				// 显隐
				if (visibleData) {
					for (const key in visibleData) {
						if (key === column.field) {
							column.selected = visibleData[column.field]
						}
					}
				}
				// 冻结
				if (fixedData) {
					for (const key in fixedData) {
						if (key === column.field) {
							column.fixed = fixedData[column.field]
						}
					}
				}
			})
			console.log('🚀 ~ tableColumn', tableColumn)
			this.$emit('updateStore', tableColumn)
		},
		// 必选表头设置
		checkColumnMethod ({column}) {
			let findColumn = this.tableColumn.find((col) => {
				return col.field === column.field
			})
			return !(findColumn && findColumn.required)
		},
		// 用于 type=checkbox，获取当前已选中的行数据，包含当前列表（如果 isFull=true 包含完整列表）
		getCheckboxRecords (isFull) {
			return this.$refs.xGrid.getCheckboxRecords(isFull)
		}
	},
	computed: {
		tableColumnOpr () {
			// console.log("触发", this.tableData);
			let tableColumn = this.tableColumn

		}
	},
}
</script>

<style lang="scss" scoped>
    .grid-class{
        position: relative;
        height: 100%;
        width: 100%;
    }
    .table-title{
        height: 50px;
        width: 200px;
        font-weight: bold;
        font-size: 20px;
        position: absolute;
        top: 0;
        left: calc(50% - 100px);
        z-index: 9;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .button-title{
        height: 50px;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 9;
        display: flex;
        align-items: center;
    }

</style>
